package com.code.commons.web.interceptor;

import com.code.commons.enums.CallSourceEnum;
import com.code.commons.enums.ResultCode;
import com.code.commons.exceptions.BusinessException;
import com.code.commons.util.IpUtil;
import com.code.commons.util.StringUtil;
import com.code.commons.web.annotations.ExcelExport;
import com.code.commons.web.constants.HeaderConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * HEADER头参数校验
 * Header头参数大小写不敏感，比如参数X-Token和X-TOEKN是一个参数
 *
 * @author tangyifei
 * @since 2019-5-24 10:59:29
 */
@Slf4j
public class HeaderParamsCheckInterceptor implements HandlerInterceptor {

//    private static final String MIN_APP_VERSION = "6.0";

    private static final String MIN_API_VERSION = "1.0";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            ExcelExport excelExport = method.getAnnotation(ExcelExport.class);
            if (null != excelExport) {
                return true;
            }
            String callSource = request.getHeader(HeaderConstants.CALL_SOURCE);
            String apiVersion = request.getHeader(HeaderConstants.API_VERSION);
            String appVersion = request.getHeader(HeaderConstants.APP_VERSION);

            log.info("请求的ip：【{}】", IpUtil.getRealIp(request));

            if (StringUtil.isAnyBlank(callSource, apiVersion)) {
                log.info("调用来源、API版本号不能为空");
                throw new BusinessException(ResultCode.PARAM_NOT_COMPLETE);
            }

            try {
                Double.valueOf(apiVersion);
            } catch (NumberFormatException e) {
                log.error("api版本号无法转换为double类型");
                throw new BusinessException(ResultCode.PARAM_IS_INVALID);
            }

            if (Double.valueOf(apiVersion).compareTo(Double.valueOf(MIN_API_VERSION)) < 0) {
                throw new BusinessException(ResultCode.API_VERSION_TOO_LOW);
            }

            if ((CallSourceEnum.ANDROID.name().equals(callSource) || CallSourceEnum.IOS.name().equals(callSource)) && StringUtil.isEmpty(appVersion)) {
                log.info("APP版本号不能为空");
                throw new BusinessException(ResultCode.PARAM_NOT_COMPLETE);
            }

            //TODO 这边注意，由于每一个app在升级的时候要更新版本号，所以数据库中的app_upgrade表的相关APP的版本号要在升级的时候跟app端沟通并修改相应的版本号，这里最好从数据库的app_upgrade表中查，不要在这写死，因为写死APP升级的时候这边要改，数据库也要改，后期优化
//            if (Double.valueOf(appVersion).compareTo(Double.valueOf(MIN_APP_VERSION)) < 0) {
//                throw new BusinessException(ResultCode.APP_VERSION_TOO_LOW);
//            }

            if (!CallSourceEnum.isValid(callSource)) {
                log.info("非法的调用来源");
                throw new BusinessException(ResultCode.PARAM_IS_INVALID);
            }

        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // nothing to do
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // nothing to do
    }

}
